﻿#define _CRT_SECURE_NO_WARNINGS 1

//赋值兼容转换
//并没有产生临时对象
#include<iostream>
#include<vector>
using namespace std;

//class Person
//{
//public:
//	void identity()
//	{
//		cout << "void identity()" << _name << endl;
//		cout << _age << endl;
//	}
//	string _name = ""; // 姓名 
//	string _address; // 地址 
//	string _tel; // 电话 
//	int _age = 18; // 年龄
//};
//
//class Student : public Person
//{
//public:
//	// 学习 
//	void study()
//	{
//		// ...
//	}
//protected:
//	int _stuid; // 学号 
//};
//
//class Teacher : public Person
//{
//public:
//	// 授课 
//	void teaching()
//	{
//		//...
//	}
//protected:
//	string title; // 职称 
//};
//
//int main()
//{
//	Student sobj;
//	// 切片
//	Person pobj = sobj;
//	Person* pp = &sobj;
//	Person& rp = sobj;
//	// 父类对象不能给子类对象（强转也不行）
//	// 父类对象的指针和引用可以给子类对象的指针和引用（需要强转）
//	Student* ps = (Student*)pp;//如果父类指针本身就指向子类对象，才安全
//	rp._name = "张三";// 如果_name不是public，在mian不能访问
//
//	int i = 1;
//	double d = 1;
//	const double& rd = i;
//	return 0;
//}

//class Person
//{
//protected:
//	string _name = "⼩李⼦"; // 姓名 
//	int _num = 111; // ⾝份证号 
//};
//
//class Student : public Person
//{
//public:
//	void Print()
//	{
//		cout << " 姓名:" << _name << endl;
//		cout << " ⾝份证号:" << Person::_num << endl; // 111
//		// 子类的成员变量隐藏了父类的，指定父类的类域可以绕过隐藏
//		cout << " 学号:" << _num << endl; // 999
//	}
//protected:
//	int _num = 999; // 学号 
//};
//int main()
//{
//	Student s1;
//	s1.Print();
//
//	return 0;
//};

// 函数重载：要求在同一个作用域（父类和子类不是同一个作用域）
// 隐藏：父类和子类中有同名成员，子类成员将屏蔽父类的同名成员（可以指定类域来绕过隐藏）
// 只要函数名相同就构成隐藏
//（如果main中调用func()但是子类有func(int i)父类有func(),并不会去调用父类的，因为被隐藏了）
//class A
//{
//public:
//	void fun()
//	{
//		cout << "func()" << endl;
//	}
//};
//class B : public A
//{
//public:
//	void fun(int i)
//	{
//		cout << "func(int i)" << i << endl;
//	}
//};
//int main()
//{
//	B b;
//	b.fun(10);
//	// b.fun();报错，被隐藏
//	b.A::fun();// 可以指定作用域绕过隐藏
//
//	return 0;
//};


class Person
{
public:
	Person(const char* name = "peter")
		: _name(name)
	{
		cout << "Person()" << endl;
	}

	Person(const Person& p)
		: _name(p._name)
	{
		cout << "Person(const Person& p)" << endl;
	}

	Person& operator=(const Person& p)
	{
		cout << "Person operator=(const Person& p)" << endl;
		if (this != &p)
			_name = p._name;

		return *this;
	}

	~Person()
	{
		cout << "~Person()" << endl;
	}
protected:
	string _name; // 姓名 
};

class Student : public Person
{
public:
	// 子类的构造函数必须调用父类的构造函数初始化父类的那一部分
	//（在子类中编译器自动生成的默认构造会自动调用父类的构造函数）
	Student(const char* name, int num)
		: Person(name)// <-显示调用父类的构造函数（像是调用匿名对象一样）
		, _num(num)
	{
		cout << "Student()" << endl;
	}
	// 子类默认生成的拷贝构造：内置：值拷贝，类：调用类的，父类：调用父类的
	// 子类的拷贝构造可以不用自己写，自己生成的就够用了
	// 如果说有需要深拷贝的资源，才需要自己实现
	Student(const Student& s)
		// 初始化列表跟出现的顺序无关，和声明的顺序有关，父类对象在最前面
		: Person(s)// 赋值兼容转换（子给父）
		, _num(s._num)
	{
		cout << "Student(const Student& s)" << endl;
	}
	// 子类默认生成的赋值重载：内置：值拷贝，类：调用类的，父类：调用父类的
	// 子类的赋值重载可以不用自己写，自己生成的就够用了
	// 如果说有需要深拷贝的资源，才需要自己实现
	Student& operator = (const Student& s)
	{
		cout << "Student& operator= (const Student& s)" << endl;
		if (this != &s)
		{
			// 构成隐藏，所以需要显⽰调⽤ 
			Person::operator =(s);
			_num = s._num;
		}
		return *this;
	}
	// 子类默认生成的析构：内置：值拷贝，类：调用类的，父类：调用父类的
	// 子类的析构可以不用自己写，自己生成的就够用了
	// 如果说有需要深拷贝的资源，才需要自己实现

	// 析构函数会被特殊处理成destructor()
	
	~Student()
	{
		// 子类的析构和父类的析构构成隐藏关系
		// 不需要显示调用，子类析构函数之后，会自动调用父类析构函数
		// Person::~Person();
		// 要保证析构顺序先子后父
		cout << "~Student()" << endl;
	}
	// 子类默认生成的构造函数的行为
	// 1.内置类型->不确定
	// 2.自定义类型->调用默认构造
	// 3.继承过来的父类成员看成一个整体对象，要求调用父类的默认构造
protected:
	int _num; //学号 
};

int main()
{
	Student s1("jack", 18);
	Student s2(s1);
	Student s3("rose", 17);
	s1 = s3;

	return 0;
}